﻿#region License
/* Copyright (C) 2009 Tim Coulter
 * 
 * This file is part of ExtremeML.
 * 
 * ExtremeML is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation either version
 * 2 of the License, or (at your option) any later version.
 * 
 * ExtremeML is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
*/
#endregion

using System;

namespace ExtremeML.Builder
{
	/// <summary>
	/// Simulates the required functionality of <see cref="Type"/> for wrapper types that do not yet exist.
	/// </summary>
	public class WrapperTypeInfo
	{
		private const string OpenXmlRootNamespace = "DocumentFormat.OpenXml";
		private const string ProjectRootNamespace = "ExtremeML";
		private const string WrapperSuffix = "Wrapper";
		private const string CollectionSuffix = "Collection";

		public WrapperTypeInfo(
			Type wrappedType,
			bool collection)
		{
			WrappedType = wrappedType;
			Namespace = GetEquivalentNamespace(WrappedType);
			Name = GetWrapperClassName(WrappedType, collection);
		}

		/// <summary>
		/// Gets the <see cref="Type"/> wrapped by this instance.
		/// </summary>
		public Type WrappedType { get; private set; }
	
		/// <summary>
		/// Gets the name of the type served by this instance.
		/// </summary>
		public string Name { get; private set; }

		/// <summary>
		/// Gets the namespace of the type served by this instance.
		/// </summary>
		public string Namespace { get; set; }

		/// <summary>
		/// Gets the full name of the type served by this instance.
		/// </summary>
		public string FullName
		{
			get { return Namespace + "." + Name; }
		}

		/// <summary>
		/// Returns the local project namespace string that is equivalent to that of the passed <see cref="Type"/>.
		/// </summary>
		private static string GetEquivalentNamespace(
			Type type)
		{
			if (type.IsGenericType)
			{
				type = Lookup.GetGenericContainedType(type);
			}

			if (type.Namespace.StartsWith(OpenXmlRootNamespace))
			{
				return type.Namespace.Replace(OpenXmlRootNamespace, ProjectRootNamespace);
			}
			else
			{
				return type.Namespace;
			}
		}

		/// <summary>
		/// Returns the wrapper class name for the specified wrapped type and storage context.
		/// </summary>
		private static string GetWrapperClassName(
			Type type,
			bool collection)
		{
			if (type.IsGenericType)
			{
				type = Lookup.GetGenericContainedType(type);
			}

			if (collection)
			{
				return type.Name + WrapperSuffix + CollectionSuffix;
			}
			else
			{
				return type.Name + WrapperSuffix;
			}
		}
	}
}
